<template>
  <view class="uni-table-scroll" :class="{ 'table--border': border, 'border-none': !noData }">
    <!-- #ifdef H5 -->
    <table class="uni-table" border="0" cellpadding="0" cellspacing="0" :class="{ 'table--stripe': stripe }"
      :style="{ 'min-width': minWidth + 'px' }">
      <slot></slot>
      <view v-if="noData" class="uni-table-loading">
        <view class="uni-table-text" :class="{ 'empty-border': border }">{{ emptyText }}</view>
      </view>
      <view v-if="loading" class="uni-table-mask" :class="{ 'empty-border': border }">
        <div class="uni-table--loader"></div>
      </view>
    </table>
    <!-- #endif -->
    <!-- #ifndef H5 -->
    <view class="uni-table" :style="{ 'min-width': minWidth + 'px' }" :class="{ 'table--stripe': stripe }">
      <slot></slot>
      <view v-if="noData" class="uni-table-loading">
        <view class="uni-table-text" :class="{ 'empty-border': border }">{{ emptyText }}</view>
      </view>
      <view v-if="loading" class="uni-table-mask" :class="{ 'empty-border': border }">
        <div class="uni-table--loader"></div>
      </view>
    </view>
    <!-- #endif -->
  </view>
</template>

<script>
  /**
   * Table 表格
   * @description 用于展示多条结构类似的数据
   * @tutorial https://ext.dcloud.net.cn/plugin?id=3270
   * @property {Boolean} 	border 				是否带有纵向边框
   * @property {Boolean} 	stripe 				是否显示斑马线
   * @property {Boolean} 	type 					是否开启多选
   * @property {String} 	emptyText 			空数据时显示的文本内容
   * @property {Boolean} 	loading 			显示加载中
   * @event {Function} 	selection-change 	开启多选时，当选择项发生变化时会触发该事件
   */
  export default {
    name: 'uniTable',
    options: {
      virtualHost: true
    },
    emits: ['selection-change'],
    props: {
      data: {
        type: Array,
        default () {
          return []
        }
      },
      // 是否有竖线
      border: {
        type: Boolean,
        default: false
      },
      // 是否显示斑马线
      stripe: {
        type: Boolean,
        default: false
      },
      // 多选
      type: {
        type: String,
        default: ''
      },
      // 没有更多数据
      emptyText: {
        type: String,
        default: '没有更多数据'
      },
      loading: {
        type: Boolean,
        default: false
      },
      rowKey: {
        type: String,
        default: ''
      }
    },
    data() {
      return {
        noData: true,
        minWidth: 0,
        multiTableHeads: []
      }
    },
    watch: {
      loading(val) {},
      data(newVal) {
        let theadChildren = this.theadChildren
        let rowspan = 1
        if (this.theadChildren) {
          rowspan = this.theadChildren.rowspan
        }

        // this.trChildren.length - rowspan
        this.noData = false
        // this.noData = newVal.length === 0 
      }
    },
    created() {
      // 定义tr的实例数组
      this.trChildren = []
      this.thChildren = []
      this.theadChildren = null
      this.backData = []
      this.backIndexData = []
    },

    methods: {
      isNodata() {
        let theadChildren = this.theadChildren
        let rowspan = 1
        if (this.theadChildren) {
          rowspan = this.theadChildren.rowspan
        }
        this.noData = this.trChildren.length - rowspan <= 0
      },
      /**
       * 选中所有
       */
      selectionAll() {
        let startIndex = 1
        let theadChildren = this.theadChildren
        if (!this.theadChildren) {
          theadChildren = this.trChildren[0]
        } else {
          startIndex = theadChildren.rowspan - 1
        }
        let isHaveData = this.data && this.data.length.length > 0
        theadChildren.checked = true
        theadChildren.indeterminate = false
        this.trChildren.forEach((item, index) => {
          if (!item.disabled) {
            item.checked = true
            if (isHaveData && item.keyValue) {
              const row = this.data.find(v => v[this.rowKey] === item.keyValue)
              if (!this.backData.find(v => v[this.rowKey] === row[this.rowKey])) {
                this.backData.push(row)
              }
            }
            if (index > (startIndex - 1) && this.backIndexData.indexOf(index - startIndex) === -1) {
              this.backIndexData.push(index - startIndex)
            }
          }
        })
        // this.backData = JSON.parse(JSON.stringify(this.data))
        this.$emit('selection-change', {
          detail: {
            value: this.backData,
            index: this.backIndexData
          }
        })
      },
      /**
       * 用于多选表格，切换某一行的选中状态，如果使用了第二个参数，则是设置这一行选中与否（selected 为 true 则选中）
       */
      toggleRowSelection(row, selected, ignoreDisabled = false) {
        // if (!this.theadChildren) return
        row = [].concat(row)
        this.trChildren.forEach((item, index) => {
          // if (item.keyValue) {

          const select = row.findIndex(v => {
            //
            if (typeof v === 'number') {
              return v === index - 1
            } else {
              return v[this.rowKey] === item.keyValue
            }
          })
          let ischeck = item.checked
          if (select !== -1 && !item.disabled) {
            if (typeof selected === 'boolean') {
              item.checked = selected
            } else {
              item.checked = !item.checked
            }
            if (ischeck !== item.checked) {
              this.check(item.rowData || item, item.checked, item.rowData ? item.keyValue : null, true)
            }
          } else if (select !== -1 && item.disabled && typeof selected === 'boolean' && ignoreDisabled == true) {
            item.checked = selected
          }
          // }
        })
        this.$emit('selection-change', {
          detail: {
            value: this.backData,
            index: this.backIndexData
          }
        })
      },

      /**
       * 用于多选表格，清空用户的选择
       */
      clearSelection() {
        let theadChildren = this.theadChildren
        if (!this.theadChildren) {
          theadChildren = this.trChildren[0]
        }
        // if (!this.theadChildren) return
        theadChildren.checked = false
        theadChildren.indeterminate = false
        this.trChildren.forEach(item => {
          // if (item.keyValue) {
          if (!item.disabled) {
            item.checked = false
          }
          // }
        })
        this.backData = []
        this.backIndexData = []
        this.$emit('selection-change', {
          detail: {
            value: [],
            index: []
          }
        })
      },
      /**
       * 用于多选表格，切换所有行的选中状态
       */
      toggleAllSelection() {
        let list = []
        let startIndex = 1
        let theadChildren = this.theadChildren
        if (!this.theadChildren) {
          theadChildren = this.trChildren[0]
        } else {
          startIndex = theadChildren.rowspan - 1
        }
        this.trChildren.forEach((item, index) => {
          if (!item.disabled) {
            if (index > (startIndex - 1)) {
              list.push(index - startIndex)
            }
          }
        })
        this.toggleRowSelection(list)
      },

      /**
       * 选中\取消选中
       * @param {Object} child
       * @param {Object} check
       * @param {Object} rowValue
       */
      check(child, check, keyValue, emit) {
        let theadChildren = this.theadChildren
        if (!this.theadChildren) {
          theadChildren = this.trChildren[0]
        }



        let childDomIndex = this.trChildren.findIndex((item, index) => child === item)
        if (childDomIndex < 0) {
          childDomIndex = this.data.findIndex(v => v[this.rowKey] === keyValue) + 1
        }
        const dataLen = this.trChildren.filter(v => !v.disabled && v.keyValue).length
        if (childDomIndex === 0) {
          check ? this.selectionAll() : this.clearSelection()
          return
        }

        if (check) {
          if (keyValue) {
            this.backData.push(child)
          }
          this.backIndexData.push(childDomIndex - 1)
        } else {
          const index = this.backData.findIndex(v => v[this.rowKey] === keyValue)
          const idx = this.backIndexData.findIndex(item => item === childDomIndex - 1)
          if (keyValue) {
            this.backData.splice(index, 1)
          }
          this.backIndexData.splice(idx, 1)
        }

        const domCheckAll = this.trChildren.find((item, index) => index > 0 && !item.checked && !item.disabled)
        if (!domCheckAll) {
          theadChildren.indeterminate = false
          theadChildren.checked = true
        } else {
          theadChildren.indeterminate = true
          theadChildren.checked = false
        }

        if (this.backIndexData.length === 0) {
          theadChildren.indeterminate = false
        }

        if (!emit) {
          this.$emit('selection-change', {
            detail: {
              value: this.backData,
              index: this.backIndexData
            }
          })
        }
      }
    }
  }
</script>

<style lang="scss">
  $border-color: #ebeef5;

  .uni-table-scroll {
    width: 100%;
    /* #ifndef APP-NVUE */
    overflow-x: auto;
    /* #endif */
  }

  .uni-table {
    position: relative;
    width: 100%;
    border-radius: 5px;
    // box-shadow: 0px 0px 3px 1px rgba(0, 0, 0, 0.1);
    background-color: #fff;
    /* #ifndef APP-NVUE */
    box-sizing: border-box;
    display: table;
    overflow-x: auto;

    ::v-deep .uni-table-tr:nth-child(n + 2) {
      &:hover {
        background-color: #f5f7fa;
      }
    }

    ::v-deep .uni-table-thead {
      .uni-table-tr {

        // background-color: #f5f7fa;
        &:hover {
          background-color: #fafafa;
        }
      }
    }

    /* #endif */
  }

  .table--border {
    border: 1px $border-color solid;
    border-right: none;
  }

  .border-none {
    /* #ifndef APP-NVUE */
    border-bottom: none;
    /* #endif */
  }

  .table--stripe {

    /* #ifndef APP-NVUE */
    ::v-deep .uni-table-tr:nth-child(2n + 3) {
      background-color: #fafafa;
    }

    /* #endif */
  }

  /* 表格加载、无数据样式 */
  .uni-table-loading {
    position: relative;
    /* #ifndef APP-NVUE */
    display: table-row;
    /* #endif */
    height: 50px;
    line-height: 50px;
    overflow: hidden;
    box-sizing: border-box;
  }

  .empty-border {
    border-right: 1px $border-color solid;
  }

  .uni-table-text {
    position: absolute;
    right: 0;
    left: 0;
    text-align: center;
    font-size: 14px;
    color: #999;
  }

  .uni-table-mask {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: rgba(255, 255, 255, 0.8);
    z-index: 99;
    /* #ifndef APP-NVUE */
    display: flex;
    margin: auto;
    transition: all 0.5s;
    /* #endif */
    justify-content: center;
    align-items: center;
  }

  .uni-table--loader {
    width: 30px;
    height: 30px;
    border: 2px solid #aaa;
    // border-bottom-color: transparent;
    border-radius: 50%;
    /* #ifndef APP-NVUE */
    animation: 2s uni-table--loader linear infinite;
    /* #endif */
    position: relative;
  }

  @keyframes uni-table--loader {
    0% {
      transform: rotate(360deg);
    }

    10% {
      border-left-color: transparent;
    }

    20% {
      border-bottom-color: transparent;
    }

    30% {
      border-right-color: transparent;
    }

    40% {
      border-top-color: transparent;
    }

    50% {
      transform: rotate(0deg);
    }

    60% {
      border-top-color: transparent;
    }

    70% {
      border-left-color: transparent;
    }

    80% {
      border-bottom-color: transparent;
    }

    90% {
      border-right-color: transparent;
    }

    100% {
      transform: rotate(-360deg);
    }
  }
</style>
